package at.jku.ase.communication.parsers;

import at.jku.ase.communication.SessionObject;
import at.jku.ase.utils.CryptUtils;

import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class TransmissionParser extends ComponentParser {
    private final Map<String, ComponentParser> delegates;

    public TransmissionParser(final SessionObject session, final XMLResponse action) {
        super(session, action);
        delegates = new HashMap<String, ComponentParser>();
        delegates.put("data", new DataParser(session, new XMLResponse() {
            public void response() throws IOException, XMLStreamException {
                System.out.println("Decrypting data...");
                File clearFile = new File(session.getId() + ".txt");
                FileOutputStream fos = new FileOutputStream(clearFile);
                fos.write(CryptUtils.decryptData(session.getData(), session.getSecretKey()));
                fos.close();
                System.out.println("Decrypted file: " + clearFile.getAbsolutePath());
            }
        }));
        delegates.put("signature", new SignatureParser(session, new XMLResponse() {
            public void response() throws IOException, XMLStreamException {
                System.out.println("Verifying Signature");
                boolean status = CryptUtils.verifySignature(session.getData(),
                        session.getSignature(),
                        session.getReceiverPublicKey());
                session.setSignStatus(status);
            }
        }));
    }

    public Object processRequest(XMLStreamReader reader) throws XMLStreamException {
        for (int event = reader.next(); event != XMLStreamConstants.END_DOCUMENT; event = reader.next()) {
            if (event == XMLStreamConstants.START_ELEMENT) {
                String element = reader.getLocalName();
                System.out.println("Parsing Element: " + element);
                if (delegates.containsKey(element)) {
                    delegates.get(element).handle(reader);
                    delegates.remove(element);
                    if (delegates.size() == 0) {
                        return null;
                    }
                }
            }
        } // rof
        return null;
    }
}
